/*							*/
/*  Indexed Sequential Access Method			*/
/*  Relational Database Systems, Inc.			*/
/*							*/
/*		Proprietary Data			*/
/*    This document contains proprietary information	*/
/* and trade secrets which are the property of		*/
/* Relational Database Systems, Inc. (RDSI). This	*/
/* document is submitted to recipient in confidence.	*/
/* The information contained herein may not be used,	*/
/* copied or disclosed in whole or in part except as	*/
/* permitted by written agreement signed by an officer	*/
/* of RDSI.						*/
/*							*/

#ifndef BTREE_INCL	/* prevent multiple includes	*/
#define BTREE_INCL

#include <errno.h>
#include "mach.h"
#include "isam.h"

#ifndef ISKERNEL
#include <sys/types.h>
#include <sys/stat.h>
#ifdef SEMPHLOCK
#include <sys/ipc.h>
#include <sys/sem.h>
#endif /* SEMPHLOCK */
#endif /* ISKERNEL */

#ifdef ISKERNEL		/* V104 */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/inode.h>
#include <sys/dir.h>
#include <sys/file.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/buf.h>
#endif /* ISKERNEL */

#ifndef STATIC
#define STATIC
#endif



#ifdef DRVRLOCK
#include <sys/lock.h>
#endif

#ifdef lint		/* keep lint from complaining */
#define VOID	_VOID_ = (int)
#else
#define VOID
#endif

#define NULL 0

#define RMODE  0
#define WMODE  1
#define RWMODE 2

#define UNLOCK 0
#define LOCKUNCOND 1
#define LOCKCOND 2
#define LOCKTEST 3
#define INDXREC 0
#define DATAREC 1

#define ERROR (-1)
#define OLD_AUTO	0x300	/* old value for ISAUTOLOCK */
#define OLD_EXCL	0x500	/* old value for ISEXCLLOCK */
#define LOCKMASK	0xF00	/* mask for lock flags	    */
#define IOMASK		0x00F	/* mask for I/O read flags  */

#define ld1(p)		((p)[0]&BYTEMASK)
#define st1(c,p)	((p)[0]=(c))

#ifdef MPM86
#undef  ldint
#undef  stint
#endif

#define ld2(p)		ldint(p)
#define st2(i,p)	stint(i,p)
#define ld4(p)		ldlong(p)
#define st4(l,p)	stlong(l,p)

#ifndef NOLONGMULT
#define longmult(x,y)	((x)*(y))
#endif

struct item
    {
    short it_flags;		/* flag bits			*/
    short it_totlen;		/* total length			*/
    short it_keylen;		/* key length			*/
    unsigned it_dupnum;		/* duplicate number		*/
    long it_ptr;		/* pointer			*/
    short it_leadcnt;		/* leading count		*/
    short it_trailcnt;		/* trailing blanks count	*/
    char it_key[KEYSIZE];	/* key value			*/
    };
#define DUP	01
#define NEXTDUP	02

struct dict
    {
    char d_magic[2];		/* magic number = BTMAGIC	*/
    char d_dummy1[4];		/* reserved bytes = 2,2,4,4	*/
    char d_idxsize[2];		/* size of index record		*/
    char d_nkeys[2];		/* number of keys defined	*/
    char d_cflag[1];		/* compression flag bits	*/
    char d_dflag[1];		/* duplicates flag bits		*/
    char d_version[1];		/* file version number		*/
    char d_recsize[2];		/* data record size		*/
    char d_keysnode[4];		/* key's description node	*/
    char d_dummy2[6];
    char d_freedata[4];		/* free data file record list	*/
    char d_freenode[4];		/* free b-tree node list	*/
    char d_nextdata[4];		/* next data file record	*/
    char d_nextnode[4];		/* next b-tree node		*/
    char d_transaction[4];	/* transaction number		*/
    char d_uniqid[4];		/* next available unique id	*/
    char d_audit[4];		/* audit trail info		*/
    };

struct node
    {
    char n_used[2];		/* num bytes used in this node	*/
    char n_items[507];		/* items with greater pointer	*/
    char n_index;		/* index number			*/
    char n_level;		/* 0 = leaf, 1..N = internal	*/
    };

struct free
    {
    char fn_used[2];		/* num bytes of free entries	*/
    char fn_next[4];		/* ptr to next free list node	*/
    char fn_free[126] [4];	/* free entries			*/
    char fn_kind;		/* FE = free nodes, FF = data	*/
    char fn_type;		/* = 7F				*/
    };

struct keyn
    {
    char kn_used[2];		/* num bytes used		*/
    char kn_next[4];		/* ptr to next key desc node	*/
    char kn_keys[503];		/* key descriptions		*/
    char kn_flag;		/* = FF				*/
    char kn_type;		/* = 7E				*/
    };

struct audt
    {
    char an_used[2];		/* num bytes used		*/
    char an_flags[2];		/* audit flags			*/
    char an_filename[PATHSIZE];	/* audit trail file name	*/
    char an_type;		/* = 7D				*/
    };

#ifdef ZCC	/* for ONIX zcc C-compiler	*/
struct ifile {};
#endif

struct buff			/* V104 */
    {
    short bf_flags;		/* flags			*/
    struct buff *bf_forw;	/* forward pointer		*/
    struct buff *bf_back;	/* backward pointer		*/
#ifdef ISKERNEL			/* V104 */
    struct buf *bf_bp;		/* kernel buffer pointer	*/
#else
    struct ifile *bf_filep;	/* file pointer			*/
#endif
    long  bf_daddr;		/* disk address			*/
    union
	{
	struct dict *bf_dict;	/* ptr to dictionary		*/
	struct keyn *bf_keyn;	/* ptr to key desc node		*/
	struct node *bf_node;	/* ptr to btree node		*/
	struct free *bf_free;	/* ptr to free list		*/
	struct audt *bf_audt;	/* ptr to audit trail info	*/
	char *bf_addr;		/* pointer to raw data		*/
	int  *bf_words;		/* int pointer to raw data	*/
	} bf_un;
    short bf_used;		/* # bytes used in node		*/
    char bf_type;		/* type byte in node		*/
    char bf_level;		/* b-tree level			*/
    };
#define BFMODF 001		/* buffer modified		*/
#define BFDONE 002		/* buffer contains data		*/
#define BFBUSY 004		/* buffer in use		*/
#define BFKBUF 010		/* kernel buffer allocated	*/
#define BFDICT 020		/* buffer contains dictionary	*/

struct tree
    {
    long t_node;		/* btree node number		*/
    short t_offset;		/* offset into node		*/
    short t_nextoff;		/* offset of next item in node	*/
    short t_used;		/* number bytes used in node	*/
    };
#define BEGFILE 01		/* at beginning of file		*/
#define ENDFILE 02		/* at end of file		*/

#ifndef ONIXLOCK
#ifndef DRVRLOCK
struct lock
    {
    short l_nopens;		/* num open locks, -1 = excl	*/
    short l_filelock;		/* file lock flag		*/
    short l_procid[NLOCKS];	/* process ids, 0 = no lock	*/
    long l_recnum[NLOCKS];	/* record numbers		*/
    };
#endif /* DRVRLOCK */
#endif /* ONIXLOCK */

struct ifile
    {
    short f_flags;
    short f_ucount;		/* number of opens		*/
    /*long f_fileid;*/		/* unique file identifier	*/
    dev_t f_device;		/* new fileid*/
    ino_t f_inum;
#ifdef SEMPHLOCK
    short f_semid;		/* SYSTEM V semaphore ident	*/
#endif /* SEMPHLOCK */
    long f_version;		/* transaction version number	*/
    struct buff *f_dicbp;	/* ptr to dictionary buffer	*/
#ifdef ISKERNEL			/* V104 */
    struct inode *f_datfd;	/* data inode ptr		*/
    struct inode *f_idxfd;	/* index inode ptr		*/
    struct inode *f_audfd;	/* audit inode ptr		*/
#else
    short f_datfd;		/* data file fd			*/
    short f_idxfd;		/* index file fd		*/
    short f_audfd;		/* audit file fd		*/
#endif
#ifdef CREATLOCK
    short f_lokfd;		/* lock file fd			*/
#endif
    short f_datsize;		/* data record size		*/
    short f_idxsize;		/* index record size		*/
#ifdef MEMLOCK
    struct lock f_locks;	/* in memory lock table		*/
#define locks	filep->f_locks
#endif
    };
#define FMODF	01		/* file has been modified	*/
#define FAUDOPEN 04		/* audit trail is open		*/

struct open
    {
    short o_flags;		/* status flags			*/
    short o_procid;		/* process id number		*/
    short o_userid;		/* user id number		*/
    short o_mode;		/* open file mode		*/
    long  o_version;		/* transaction version number	*/
    struct ifile *o_filep;	/* file descriptor pointer	*/
    struct keydesc o_curkey;	/* current key descriptor	*/
    struct item o_curitem;	/* current item value		*/
    struct tree o_trees[NTREES];/* current tree path		*/
    short o_trlev;		/* current tree level		*/
    short o_trleaf;		/* tree level of leaf node	*/
    short o_trflags;		/* tree flags			*/
    };
#define OBUSY	 0001		/* open struct in use		*/
#define OCURPOS	 0004		/* current position exists	*/
#define OCURREAD 0010		/* current record has been read	*/
#define ODUPL	 0020		/* duplicate created or read	*/
#define OFLOCK	 0040		/* have whole file locked	*/
#define OSLOCK   0100		/* have semaphore lock		*/
#define OFLUSH   0200		/* write out buffers to disk	*/

struct buff *bfread();
struct buff *bfgetblk();
struct buff *bfgetclr();

long lseek();
long allocrec();
struct ifile *allocfile();
#ifdef ISALLOC
char *malloc();
#endif /* ISALLOC */

#ifdef NOLONGMULT
long longmult();
#endif /* NOLONGMULT */

#endif /* BTREE_INCL */

